package cn.iocoder.yudao.framework.datasource.core;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 数据源切换服务实现类
 * 提供数据源切换的业务服务，自动检查和创建数据源连接，与数据源配置服务集成
 *
 * @author 芋道源码
 */
@Slf4j
@Service
public class ChangeDataSourceServiceImpl implements ChangeDataSourceService {

    @Autowired(required = false)
    private DynamicRoutingDataSource dynamicRoutingDataSource;

    @Override
    public void changeDS(String dataSourceKey) {
        if (StrUtil.isBlank(dataSourceKey)) {
            log.warn("数据源标识为空，切换到默认数据源");
            restoreDefaultDS();
            return;
        }

        if (dynamicRoutingDataSource == null) {
            log.warn("DynamicRoutingDataSource 未初始化，使用默认数据源");
            return;
        }

        if (!existsDataSource(dataSourceKey)) {
            log.error("数据源 {} 不存在，无法切换", dataSourceKey);
            throw new RuntimeException("数据源不存在: " + dataSourceKey);
        }

        DataSourceContextHolder.setDataSource(dataSourceKey);
        log.info("成功切换到数据源: {}", dataSourceKey);
    }

    @Override
    public void changeDS(DataSourceConfigDO dataSourceConfig) {
        if (dataSourceConfig == null || StrUtil.isBlank(dataSourceConfig.getDataSourceKey())) {
            log.warn("数据源配置为空，切换到默认数据源");
            restoreDefaultDS();
            return;
        }

        if (dynamicRoutingDataSource == null) {
            log.warn("DynamicRoutingDataSource 未初始化，使用默认数据源");
            return;
        }

        // 检查并创建数据源
        dynamicRoutingDataSource.checkCreateDataSource(dataSourceConfig);

        // 切换到指定数据源
        DataSourceContextHolder.setDataSource(dataSourceConfig.getDataSourceKey());
        log.info("成功切换到数据源: {}", dataSourceConfig.getDataSourceKey());
    }

    @Override
    public void restoreDefaultDS() {
        DataSourceContextHolder.removeDataSource();
        log.debug("已恢复到默认数据源");
    }

    @Override
    public boolean existsDataSource(String dataSourceKey) {
        if (StrUtil.isBlank(dataSourceKey) || dynamicRoutingDataSource == null) {
            return false;
        }
        
        return dynamicRoutingDataSource.getDynamicDataSources().containsKey(dataSourceKey);
    }
}